home *** CD-ROM | disk | FTP | other *** search
/ Programmer Power Tools / Programmer Power Tools.iso / database / mth.c < prev    next >
Text File  |  1984-05-21  |  8KB  |  358 lines

  1. /* SDB - string arithmetic routines */
  2.  
  3. #include "ctype.h"  /*dns*/
  4.  
  5. /* useful definitions */
  6. #define TRUE            1
  7. #define FALSE           0
  8. #define NUMBERMAX       99
  9. #define EOS             0
  10.  
  11. /* db_cmp - compare two signed numeric strings */
  12. int db_cmp(arg1,arg2)
  13.   char *arg1,*arg2;
  14. {
  15.     int sign1,sign2;
  16.  
  17.     /* get the signs of the arguments */
  18.     sign1 = getsign(&arg1);
  19.     sign2 = getsign(&arg2);
  20.  
  21.     /* compute the result */
  22.     if (sign1 == sign2) {
  23.         if (sign1 == 1)
  24.             return (compare(arg1,arg2));
  25.         else
  26.             return (compare(arg2,arg1));
  27.     }
  28.  
  29.     /* signs are different */
  30.     return (sign1);
  31. }
  32.  
  33. /* db_add - add two signed numeric strings */
  34. db_add(result,arg1,arg2)
  35.   char *result,*arg1,*arg2;
  36. {
  37.     int signr,sign1,sign2;
  38.     char rtmp[NUMBERMAX+2],*rptr;
  39.  
  40.     /* get the signs of the arguments */
  41.     sign1 = getsign(&arg1);
  42.     sign2 = getsign(&arg2);
  43.  
  44.     /* compute the result */
  45.     if (sign1 == sign2) {
  46.         signr = sign1;
  47.         add(rtmp,arg1,arg2);
  48.     }
  49.     else
  50.         switch (compare(arg1,arg2)) {
  51.         case -1:
  52.                 signr = sign2;
  53.                 sub(rtmp,arg2,arg1);
  54.                 break;
  55.         case 0:
  56.                 strcpy(result,"0");
  57.                 return;
  58.         case 1:
  59.                 signr = sign1;
  60.                 sub(rtmp,arg1,arg2);
  61.                 break;
  62.         }
  63.  
  64.     /* insert the sign */
  65.     if (signr == -1)
  66.         strcpy(result,"-");
  67.     else
  68.         result[0] = EOS;
  69.  
  70.     /* eliminate possible leading zeros */
  71.     for (rptr = rtmp; *rptr == '0'; rptr++)
  72.         ;
  73.  
  74.     /* copy the result */
  75.     if (*rptr != EOS)
  76.         strcat(result,rptr);
  77.     else
  78.         strcat(result,"0");
  79. }
  80.  
  81. /* db_sub - subtract two signed numeric strings */
  82. db_sub(result,arg1,arg2)
  83.   char *result,*arg1,*arg2;
  84. {
  85.     int signr,sign1,sign2;
  86.     char rtmp[NUMBERMAX+2],*rptr;
  87.  
  88.     /* get the signs of the arguments */
  89.     sign1 = getsign(&arg1);
  90.     sign2 = getsign(&arg2);
  91.  
  92.     /* invert the sign of arg2 */
  93.     sign2 = -sign2;
  94.  
  95.     /* compute the result */
  96.     if (sign1 == sign2) {
  97.         signr = sign1;
  98.         add(rtmp,arg1,arg2);
  99.     }
  100.     else
  101.         switch (compare(arg1,arg2)) {
  102.         case -1:
  103.                 signr = sign2;
  104.                 sub(rtmp,arg2,arg1);
  105.                 break;
  106.         case 0:
  107.                 strcpy(result,"0");
  108.                 return;
  109.         case 1:
  110.                 signr = sign1;
  111.                 sub(rtmp,arg1,arg2);
  112.                 break;
  113.         }
  114.  
  115.     /* insert the sign */
  116.     if (signr == -1)
  117.         strcpy(result,"-");
  118.     else
  119.         result[0] = EOS;
  120.  
  121.     /* eliminate a possible leading zero */
  122.     for (rptr = rtmp; *rptr == '0'; rptr++)
  123.         ;
  124.  
  125.     /* copy the result */
  126.     if (*rptr != EOS)
  127.         strcat(result,rptr);
  128.     else
  129.         strcat(result,"0");
  130. }
  131.  
  132. /* add - add two unsigned numeric strings */
  133. static add(result,arg1,arg2)
  134.   char *result,*arg1,arg2;
  135. {
  136.     char *vr,*v1,*v2,*vx;
  137.     int carry,i,nmin,nmax,nd1,nd2;
  138.  
  139.  
  140.     /* get number of digits in each argument */
  141.     nd1 = getlen(arg1);
  142.     nd2 = getlen(arg2);
  143.  
  144.     /* compute the address of the last digit + 1 */
  145.     v1 = arg1 + nd1;
  146.     v2 = arg2 + nd2;
  147.  
  148.     /* compute minimum and maximum of nd1 and nd2 */
  149.     if (nd1 < nd2) {
  150.         nmin = -nd1;
  151.         nmax = -nd2;
  152.         vx = v2;
  153.     }
  154.     else {
  155.         nmin = -nd2;
  156.         nmax = -nd1;
  157.         vx = v1;
  158.     }
  159.  
  160.     /* compute the address of the last result digit + 1 */
  161.     vr = result - nmax; vr[0] = EOS;
  162.  
  163.     /* initialize the carry */
  164.     carry = 0;
  165.  
  166.     /* add the digits */
  167.     for (i = -1; i >= nmin; i--) {
  168.  
  169.         /* check for decimal point */
  170.         if (v1[i] == '.')
  171.             vr[i] = '.';
  172.         else {
  173.  
  174.             /* add the current pair of digits with the carry */
  175.             vr[i] = v1[i] + v2[i] + carry - '0';
  176.  
  177.             /* check for carry */
  178.             if (vr[i] > '9') {
  179.                 vr[i] -= 10;
  180.                 carry = 1;
  181.             }
  182.             else
  183.                 carry = 0;
  184.         }
  185.     }
  186.  
  187.     /* add the remaining digits */
  188.     for (; i >= nmax; i--) {
  189.  
  190.         /* add the current digit with the carry */
  191.         vr[i] = vx[i] + carry;
  192.  
  193.         /* check for carry */
  194.         if (vr[i] > '9') {
  195.             vr[i] -= 10;
  196.             carry = 1;
  197.         }
  198.         else
  199.             carry = 0;
  200.     }
  201.  
  202.     /* check for a carry out and shift digits if necessary */
  203.     if (carry == 1) {
  204.  
  205.         /* shift the digits */
  206.         for (i = -nmax; i >= 0; i--)
  207.             result[i+1] = result[i];
  208.         result[0] = '1';
  209.     }
  210. }
  211.  
  212. /* sub - subtract two unsigned numeric strings */
  213. static sub(result,arg1,arg2)
  214.   char *result,*arg1,arg2;
  215. {
  216.     char *vr,*v1,*v2,*vx;
  217.     int borrow,i,nmin,nmax,nd1,nd2;
  218.  
  219.     /* get number of digits in each argument */
  220.     nd1 = getlen(arg1);
  221.     nd2 = getlen(arg2);
  222.  
  223.     /* compute the address of the last digit + 1 */
  224.     v1 = arg1 + nd1;
  225.     v2 = arg2 + nd2;
  226.  
  227.     /* compute minimum and maximum of nd1 and nd2 */
  228.     if (nd1 < nd2) {
  229.         nmin = -nd1;
  230.         nmax = -nd2;
  231.         vx = v2;
  232.     }
  233.     else {
  234.         nmin = -nd2;
  235.         nmax = -nd1;
  236.         vx = v1;
  237.     }
  238.  
  239.     /* compute the address of the last result digit + 1 */
  240.     vr = result - nmax; vr[0] = EOS;
  241.  
  242.     /* initialize the borrow */
  243.     borrow = 0;
  244.  
  245.     /* subtract the digits */
  246.     for (i = -1; i >= nmin; i--) {
  247.  
  248.         /* check for decimal point */
  249.         if (v1[i] == '.')
  250.             vr[i] = '.';
  251.         else {
  252.  
  253.             /* subtract the current pair of digits with the borrow */
  254.             vr[i] = v1[i] - v2[i] - borrow + '0';
  255.  
  256.             /* check for borrow */
  257.             if (vr[i] < '0') {
  258.                 vr[i] += 10;
  259.                 borrow = 1;
  260.             }
  261.             else
  262.                 borrow = 0;
  263.         }
  264.     }
  265.  
  266.     /* subtract the remaining digits */
  267.     for (; i >= nmax; i--) {
  268.  
  269.         /* subtract the current digit with the borrow */
  270.         vr[i] = vx[i] - borrow;
  271.  
  272.         /* check for borrow */
  273.         if (vr[i] < '0') {
  274.             vr[i] += 10;
  275.             borrow = 1;
  276.         }
  277.         else
  278.             borrow = 0;
  279.     }
  280. }
  281.  
  282. /* getsign - get the sign of a numeric string */
  283. static int getsign(parg)
  284.   char **parg;
  285. {
  286.     int sign;
  287.     char *p;
  288.  
  289.     /* eliminate leading spaces */
  290.     while (isspace(**parg))
  291.         *parg += 1;
  292.  
  293.     /* get the sign */
  294.     switch (**parg) {
  295.     case '+':   *parg += 1;
  296.                 sign = 1;
  297.                 break;
  298.     case '-':   *parg += 1;
  299.                 sign = -1;
  300.                 break;
  301.     default:    sign = 1;
  302.                 break;
  303.     }
  304.  
  305.     /* eliminate leading spaces and zeros */
  306.     while (isspace(**parg) || **parg == '0')
  307.         *parg += 1;
  308.  
  309.     /* if the value is zero, make sure that the sign is positive */
  310.     switch (**parg) {
  311.     case EOS:   sign = 1;
  312.                 break;
  313.     case '.':   for (p = *parg + 1; *p == '0'; p++)
  314.                     ;
  315.                 if (*p == EOS)
  316.                     sign = 1;
  317.                 break;
  318.     }
  319.  
  320.     /* return the sign */
  321.     return (sign);
  322. }
  323.  
  324. /* getlen - get the length of a numeric string */
  325. static int getlen(arg)
  326.   char *arg;
  327. {
  328.     int len;
  329.  
  330.     /* get the length of the string */
  331.     len = strlen(arg);
  332.  
  333.     /* eliminate trailing spaces */
  334.     while (isspace(arg[len-1]))
  335.         len -= 1;
  336.  
  337.     /* return the length */
  338.     return (len);
  339. }
  340.  
  341. /* compare - compare two unsigned numeric strings */
  342. static int compare(arg1,arg2)
  343.   char *arg1,*arg2;
  344. {
  345.     int len1,len2;
  346.  
  347.     /* compare lengths */
  348.     if ((len1 = getlen(arg1)) != (len2 = getlen(arg2)))
  349.         if (len1 < len2)
  350.             return (-1);
  351.         else
  352.             return (1);
  353.  
  354.     /* compare strings */
  355.     return (strcmp(arg1,arg2));
  356. }
  357.  
  358.